package com.corner.system.websocket;


import com.alibaba.fastjson2.JSON;
import com.corner.common.utils.StringUtils;
import com.corner.system.domain.CtrMsg;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;

import javax.annotation.PreDestroy;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Component
@Slf4j
@Data
@ConfigurationProperties(prefix = "websocket")
public class WebSocketClientHandler extends StandardWebSocketClient implements WebSocketHandler {
    private WebSocketSession session;
    private String url;
    public static String sessionId = null;

    /**
     * 连接WebSocket服务端
     */
//    @Scheduled(fixedDelay = 60000) // 每隔1分钟连接一次
    public void connect() throws Exception {
        WebSocketClient client = new StandardWebSocketClient();
        session = client.doHandshake(new WebSocketClientHandler(), url).get();
        log.info("Client: WebSocket connection established");
    }

    /**
     * 关闭WebSocket连接
     */
    @PreDestroy
    public void close() throws Exception {
        session.close();
    }

    /**
     * @param msg:向服务端发送的消息
     *               {
     *                 "msgId":"login","username":"admin","password":"123456","_time_":"12346789"
     *             }
     */
    public void sendMessage(CtrMsg msg) throws Exception {
        boolean open = session.isOpen();
        if(!open){
            this.connect();
        }
        String message = null;
        if(sessionId == null){
            Date date = new Date();
            long time = date.getTime();
            CtrMsg ctrMsg = new CtrMsg();
            ctrMsg.setMsgId("login");
            ctrMsg.setUsername("admin");
            ctrMsg.setPassword("111111");
            ctrMsg.set_time_(time+"");

            String s = JSON.toJSONString(ctrMsg);
            session.sendMessage(new TextMessage(s));
            return;
        }

        msg.setSessionId(sessionId);
        msg.setMsgId("control");
        ObjectMapper objectMapper = new ObjectMapper();

        String json = objectMapper.writeValueAsString(msg);

        session.sendMessage(new TextMessage(json));
    }

//    @Scheduled(fixedDelay = 5000)
//    public void sendMessage() throws Exception {
//        session.sendMessage(new TextMessage("message"));
//    }

    /**
     * 处理连接后的逻辑
     * @param session:WebSocketSession域对象,有获取通信信息,发送消息,打开关闭通道等等功能
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("Client: WebSocket connection established");
    }
    /**
     * 处理客户端发送的消息
     * @param session:WebSocketSession域对象,有获取通信信息,发送消息,打开关闭通道等等功能
     * @param message:客户端发送的文本消息
     *  {
     * "msgId":"login",
     * "return"：true,
     *   … ,
     * "sessioId":fbe8e056-c2a3-ebb7-5eb5-7e8ecae3d0ec"
     * }
     */
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        log.info("Client: Received message: " + message.getPayload());
        String payload = (String)message.getPayload();
        Map map = JSON.parseObject(payload, Map.class);
        String msgId = (String)map.get("msgId");
        String sessionId = (String)map.get("sessionId");
        Boolean flag = (Boolean)map.get("return");
        if(msgId.equals("login")){
            if(flag){
                WebSocketClientHandler.sessionId = sessionId;
                session.sendMessage(new TextMessage("Client: 获取 sessionId 成功!"));
            }else {
                session.sendMessage(new TextMessage("Client: 获取 sessionId 失败!"));
            }

        }else{
            session.sendMessage(new TextMessage("Client: Hello, server!"));

        }
    }

    /**
     * 处理发生的错误
     * @param session:WebSocketSession域对象,有获取通信信息,发送消息,打开关闭通道等等功能
     * @param exception:通信出现的异常
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.info("Client: Error Occurred: " + exception.getMessage());
    }

    /**
     * 连接关闭
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        log.info("Client: Connection Closed");
    }

    /**
     * 用于判断服务器或客户端是否支持分片消息partial message
     * WebSocket 协议规范要求所有的 WebSocket 实现都必须支持接收和处理完整的消息
     * @return boolean
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}
